
package com.sylar.lelepub.widget;

import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.concurrent.RejectedExecutionException;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.AsyncTask;
import android.util.AttributeSet;
import android.widget.ImageView;
import android.widget.ListView;

import com.sylar.lelepub.LeLePubApplication;
import com.sylar.lelepub.tools.ImageCache;

public  class RemoteImageView extends ImageView{
	
	private static int MAX_FAILURES = 3;

	public RemoteImageView(Context context, AttributeSet attrs, int defStyle) {
		super(context, attrs, defStyle);
		init();
	}

	public RemoteImageView(Context context, AttributeSet attrs) {
		super(context, attrs);
		init();
	}

	public RemoteImageView(Context context) {
		super(context);
		init();
	}

	private void init(){
	}
	
	private String mUrl;
	
	private String mCurrentlyGrabbedUrl;
	
	private int mFailure;  

	private int mPosition;

	private ListView mListView;
	private Integer mDefaultImage;

	
	public void setImageUrl(String url){
		
		if(mListView == null && mCurrentlyGrabbedUrl != null && mCurrentlyGrabbedUrl.equals(url)){
			return;
		}
		
		if(mUrl != null && mUrl.equals(url)){
			mFailure++;
			if(mFailure > MAX_FAILURES){
				loadDefaultImage();
				return;
			}
		} else {
			mUrl = url;
			mFailure = 0; 
		}

		ImageCache imageCache = LeLePubApplication.getInstance().getImageCache();
		
		/**
		 * 如果缓存中存在 则直接从缓存中加载
		 */
		if(imageCache.isCached(url)){  
			this.setImageBitmap(imageCache.get(url));
		}
		/**
		 * 若缓存中不存在，则进行异步加载
		 */
		else {
			try{
				new DownloadTask().execute(url);
			} catch (RejectedExecutionException e) {
				// do nothing, just don't crash
			}
		}
	}
	
	public void setDefaultImage(Integer resid){
		mDefaultImage = resid;
	}
	
	private void loadDefaultImage(){
		if(mDefaultImage != null)
			setImageResource(mDefaultImage);
	}
	
	public void setImageUrl(String url, int position, ListView listView){
		mPosition = position;
		mListView = listView;
		setImageUrl(url);
	}

	class DownloadTask extends AsyncTask<String, Void, String>{
		
		private String mTaskUrl;
       
		/**
		 * 这里是最终用户调用Excute时的接口，当任务执行之前开始调用此方法，可以在这里显示进度对话框。
		 */
		@Override
		public void onPreExecute() {
			loadDefaultImage();
			super.onPreExecute();
		}
       
		@Override
		public String doInBackground(String... params) {

			mTaskUrl = params[0];
			InputStream stream = null;
			URL imageUrl;
			Bitmap bmp = null;

			try {
				imageUrl = new URL(mTaskUrl);
				try {
					stream = imageUrl.openStream();
					bmp = BitmapFactory.decodeStream(stream);
					try {
						if(bmp != null){
							//将从网络加载到的图片放到缓存中
							LeLePubApplication.getInstance().getImageCache().put(mTaskUrl, bmp,true);
							
						} else {
							//TODO
						}
					} catch (NullPointerException e) {
						e.printStackTrace();
					}
				} catch (IOException e) {
					e.printStackTrace();
				} finally {
					try {
						if(stream != null){
							stream.close();
						}
					} catch (IOException e) {}
				}

			} catch (MalformedURLException e) {
				e.printStackTrace();
			}
			return mTaskUrl;
		}

		/**
		 * onPostExecute(Result)  相当于Handler 处理UI的方式
		 * 在这里面可以使用在doInBackground 得到的结果处理操作UI。
		 * 此方法在主线程执行，任务执行的结果作为此方法的参数返回
		 */
		@Override
		public void onPostExecute(String url) {
			super.onPostExecute(url);
			
			// target url may change while loading
			if(!mTaskUrl.equals(mUrl))
				return;
			//从缓存中取出在doInBackground(String... params)方法从网络加载到的图片
			Bitmap bmp = LeLePubApplication.getInstance().getImageCache().get(url);
			if(bmp == null){
				
				RemoteImageView.this.setImageUrl(url);
			} else {
				
				//如果图像从属于某一记录表更新它只有当它的可见
				if(mListView != null)
					if(mPosition < mListView.getFirstVisiblePosition() || mPosition > mListView.getLastVisiblePosition())
						return;
				
				RemoteImageView.this.setImageBitmap(bmp);
				mCurrentlyGrabbedUrl = url;
			}
		}
		
		/**
		 * 可以使用进度条增加用户体验度。 此方法在主线程执行，用于显示任务执行的进度。
		 */
		@Override
		protected void onProgressUpdate(Void... values) {
			// TODO Auto-generated method stub
			super.onProgressUpdate(values);
		}

	};

}
